"""Subversion repository log"""
import pysvn
from time import localtime
from datetime import datetime
from sqlalchemy import *
from sqlalchemy.orm import * 

from digvcs.model.meta import Base

class Repository(Base):
    """SVN Repository"""
    __tablename__ = 'svn_repositories'
    
    id  = Column(Integer, primary_key=True)
    url = Column(String(255), nullable=False, unique=True)
    
    def __init__(self, url):
        """Construct new Repository object
        
        ''url''
            non-empty repository URL
            
        """
        if url is None:
            raise exceptions.AttributeError('url is None')
        self.url = url
        
    def __repr__(self):
        return "<Repository(%s)>" % self.url

class Revision(Base):
    """SVN Revision"""
    __tablename__ = 'svn_revisions'
    
    id       = Column(Integer, primary_key=True)
    author   = Column(Unicode(32), nullable=False)
    message  = Column(UnicodeText, nullable=True)
    date     = Column(DateTime, nullable=False)
    rev_num  = Column(Integer, nullable=False)
    
    repository_id = Column(Integer, ForeignKey('svn_repositories.id'))
    repository    = relation(Repository, backref=backref('revisions'))
    
    def __init__(self, repository, author, message, date, number):
        self.repository = repository
        self.author = author
        self.message = message
        self.date = date
        self.rev_num = number
        
    def __repr__(self):
        return "<Revision(%s, %s, %s)>" % (self.author, self.date, self.rev_num)
    
class Change(Base):
    """SVN Change"""
    __tablename__ = 'svn_changes'
    
    id      = Column(Integer, primary_key=True)
    action  = Column(Unicode(4))
    path    = Column(Unicode(512))
    
    revision_id  = Column(Integer, ForeignKey('svn_revisions.id'))
    revision     = relation(Revision, backref=backref('changes'))
    
    def __init__(self, revision, action, path):
        self.revision = revision
        self.action = action
        self.path = path
        
    def __repr__(self):
        return "<Change(%s, %s)>" % (self.action, self.path)

repositories_table = Repository.__table__
revisions_table = Revision.__table__
changes_table = Change.__table__

revisions_table.append_constraint(UniqueConstraint('repository_id', 'rev_num'))

def import_repository(session, repo_url, limit=0):
    svn = pysvn.Client()
    logs = svn.log(repo_url, discover_changed_paths=True, limit=limit)
    logs.reverse()
    
    repository = Repository(repo_url)
    session.add(repository) 

    for log in logs:
        author = ""
        try:
            author = log['author']
        except KeyError:
            author = "unknown"
        rev = Revision( 
            repository = repository,
            author  = author,
            message = log['message'],
            date    = datetime(*localtime(log['date'])[:6]),
            number = log['revision'].number            
        )
        session.add(rev)
        
        for cp in log['changed_paths']:
            session.add(
                Change(
                    revision = rev,
                    action   = cp['action'],
                    path     = cp['path']
                )
            )
                
    session.flush() 
